package com.googlecode.yoohoo.io.socket.stream;

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;

import com.googlecode.yoohoo.xmppcore.model.account.IAccount;
import com.googlecode.yoohoo.xmppcore.model.account.IAccountManager;
import com.googlecode.yoohoo.xmppcore.protocol.stream.error.InternalServerError;
import com.googlecode.yoohoo.xmppcore.utils.ErrorUtils;

/*import quicklinker.server.core.model.user.IUser;
import quicklinker.server.core.model.user.IUserPersister;
import quicklinker.server.core.utils.AppUtils;
import quicklinker.server.core.xmpp.ProtocolException;
import quicklinker.server.core.xmpp.stream.errors.InternalServerError;*/

public class DefaultAuthenticationCallbackHandler implements CallbackHandler {
	private ResourceBindingNegotiant resourceBindingNegotiant;
	private String password;
	private PasswordCallback passwordCallback;
	private IAccountManager accountManager;
	
	public DefaultAuthenticationCallbackHandler(ResourceBindingNegotiant resourceBindingNegotiant,
				IAccountManager accountManager) {
		this.resourceBindingNegotiant = resourceBindingNegotiant;
		this.accountManager = accountManager;
	}
	
	@Override
	public void handle(Callback[] callbacks) throws IOException,
			UnsupportedCallbackException {
		for (Callback callback : callbacks) {
			if (callback instanceof NameCallback) {
				NameCallback nameCallback = (NameCallback)callback;
				if (accountManager == null) {
					throw ErrorUtils.createProtocolException("Null account manager.",
							new InternalServerError());
				}
				
				IAccount account = accountManager.getByName(nameCallback.getDefaultName());
				if (account != null) {
					password = account.getPassword();
					resourceBindingNegotiant.setUserName(nameCallback.getDefaultName());
				}
			} else if (callback instanceof PasswordCallback) {
				passwordCallback = (PasswordCallback)callback;
			} else if (callback instanceof AuthorizeCallback) {
				AuthorizeCallback authorizeCallback = (AuthorizeCallback)callback;
				authorizeCallback.setAuthorized(true);
			}
		}
		
		if (passwordCallback != null) {
			passwordCallback.setPassword(password == null ? null : password.toCharArray());
		}
	}

}
